<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>navigator.sendBeacon全套</title>
	</head>
	<body>
		<button class="send">发送（埋点记录）</button>

		<script>
			/**
			 * navigator.sendBeacon() 方法用于将数据异步发送到服务器。
			 *
			 * 应用场景：
			 * 1. 发送心跳包：可以使用 navigator.sendBeacon 发送心跳包，以保持与服务器的长连接，避免因为长时间没有网络请求而导致连接被关闭。
			 * 2. 埋点（常用场景）：可以使 navigator.sendBeacon 在页面关闭或卸载时记录用户在线时间，pv uv，以及错误日志上报 按钮点击次数。
			 * 3. 发送用户反馈：可以使用 navigator.sendBeacon 发送用户反馈信息，如用户意见、bug报告等，以便进行产品优化和改进。
			 *
			 * 优点：
			 * 1. 不受页面卸载过程的影响，确保数据可靠发送。
			 * 2. 异步执行，不阻塞页面关闭或跳转。
			 * 3. 使用HTML5新增的ping请求，能够支持发送跨域请求。
			 *
			 * 缺点：
			 * 1. fetch 和 ajax 都可以发送任意请求，但 sendBeacon 只能发送 POST 请求。
			 * 2. fetch 和 ajax 可以传输任意字节数据而 sendBeacon 只能传输少量字节数据(64kb以内)。
			 * 3. fetch 和 ajax 都可以指定请求头，而 sendBeacon 不能自定义请求头。
			 * 4. sendBeacon 只能传输 ArrayBuffer、 ArrayBufferview、 Blob、 DOmstring、 FormData 或 URLSearchParams 类型的数据。
			 * 5. 如果处于危险的网络环境，或者开启了广告屏蔽插件此请求将无效。
			 */

			const send = document.querySelector('.send')

			// 埋点记录（JSON数据格式）
			let json = JSON.stringify({ event: 'add' })
			let blob = new Blob([json], { type: 'application/json' })

			send.addEventListener('click', () => {
				navigator.sendBeacon('https://example.com/api/log', blob)
			})
		</script>
	</body>
</html>
